#include "mainwindow.h"
#include <QDebug>
#include <QSettings>
#include <QIcon>
#include <QStatusBar>
#include <QMenuBar>
#include <QMenu>
#include <QToolBar>
#include <QFileDialog>
#include <QMessageBox>
#include <QStandardPaths>
#include "optiondialog.h"
#include "spdlog/spdlog.h"
#include "loggername.h"
#include <QThread>
#include "generator.h"
#include <QDateTime>

MainWindow::MainWindow(QSplashScreen *splash, QWidget *parent) :
    QMainWindow(parent)
{
    this->splash = splash;
    readSettings();

    initActions();
    initMenuBar();
    initToolBar();
    initStatusBar();
    initCentralWidget();

    setWindowTitle(tr("creality3d slicer"));
    setWindowIcon(QIcon(":/images/creality3d.png"));

    splash->showMessage("xxxxx", Qt::AlignLeft | Qt::AlignBottom, Qt::white);

    const QDateTime n = QDateTime::currentDateTime();
    QDateTime now;
    do
    {
        now = QDateTime::currentDateTime();
    }
    while (n.secsTo(now) <= 6);

    QString message = tr("Ready");
    statusBar()->showMessage(message, 3000);

    auto logger = spdlog::get(LOGGER_NAME);
    logger->info("start ok");
}

MainWindow::~MainWindow()
{
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    if (QMessageBox::Yes == QMessageBox::question(this, tr("Quit"), tr("Are you sure to quit?")))
    {
        event->accept();
    }
    else
    {
        event->ignore();
    }
}

void MainWindow::readSettings()
{


//    QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName());
//    const QByteArray geometry = settings.value("geometry", QByteArray()).toByteArray();
//    if (geometry.isEmpty())
//    {
//        const QRect availableGeometry = QApplication::desktop()->availableGeometry(this);
//        resize(availableGeometry.width() / 3, availableGeometry.height() / 2);
//        move((availableGeometry.width() - width()) / 2,
//             (availableGeometry.height() - height()) / 2);
//    }
//    else
//    {
//        restoreGeometry(geometry);
//    }
}

void MainWindow::writeSettings()
{
//    QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName());
//    settings.setValue("geometry", saveGeometry());
}

void MainWindow::initActions()
{
    openAct = new QAction(QIcon(":/images/open.png"), tr("&Open"), this);
    openAct->setShortcuts(QKeySequence::Open);
    openAct->setStatusTip(tr("Open a file"));
    connect(openAct, SIGNAL(triggered(bool)), this, SLOT(showOpenFile()));

    quitAct = new QAction(QIcon(":/images/quit.png"), tr("&Quit"), this);
    quitAct->setShortcut(QKeySequence::Quit);
    quitAct->setStatusTip(tr("Quit"));
    connect(quitAct, SIGNAL(triggered()), this, SLOT(close()));

    enAct = new QAction(tr("English"), this);
    enAct->setStatusTip(tr("English"));
    enAct->setCheckable(true);
    enAct->setChecked(true);
    connect(enAct, SIGNAL(triggered(bool)), this, SLOT(langEn()));

    zhAct = new QAction(tr("Simplified Chinese"), this);
    zhAct->setStatusTip(tr("Simplified Chinese"));
    zhAct->setCheckable(true);
    zhAct->setChecked(false);
    connect(zhAct, SIGNAL(triggered(bool)), this, SLOT(langZh()));

    optionAct = new QAction(QIcon(":/images/option.png"), tr("&Option"), this);
//    settingAct->setShortcut(tr("Ctrl+S"));
    optionAct->setStatusTip(tr("Option"));
    connect(optionAct, SIGNAL(triggered()), this, SLOT(showOption()));

    aboutAct = new QAction(QIcon(":/images/about.png"), tr("&About"), this);
    aboutAct->setShortcut(tr("Ctrl+A"));
    aboutAct->setStatusTip(tr("About"));
    connect(aboutAct, SIGNAL(triggered()), this, SLOT(showAbout()));

    generateAct = new QAction(QIcon(":/images/generate.png"), tr("&Generate .gcode"), this);
    generateAct->setShortcut(tr("Ctrl+G"));
    generateAct->setStatusTip(tr("Generate .gcode"));
    connect(generateAct, SIGNAL(triggered()), this, SLOT(generateGcode()));
}

void MainWindow::initMenuBar()
{
    QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
    fileMenu->addAction(openAct);
    fileMenu->addSeparator();
    fileMenu->addAction(quitAct);

    QMenu *settingMenu = menuBar()->addMenu(tr("&Setting"));

    QMenu *langMenu = settingMenu->addMenu(tr("Language"));
    langMenu->addAction(enAct);
    langMenu->addAction(zhAct);

    settingMenu->addAction(optionAct);

    QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
    helpMenu->addAction(aboutAct);
}

void MainWindow::initToolBar()
{
    QToolBar *fileToolBar = addToolBar(tr("File"));
    fileToolBar->addAction(openAct);
    fileToolBar->addSeparator();

    QToolBar *settingToolBar = addToolBar(tr("Setting"));
    settingToolBar->addAction(optionAct);
    settingToolBar->addAction(generateAct);
    settingToolBar->addSeparator();

    QToolBar *aboutToolBar = addToolBar(tr("About"));
    aboutToolBar->addAction(aboutAct);
}

void MainWindow::initStatusBar()
{
    cuboidScaleLabel = new QLabel(this);
    cuboidScaleLabel->setText(tr("1"));
//    cuboidScaleLabel->setFixedWidth(100);

    cuboidRotationLabel = new QLabel(this);
    cuboidRotationLabel->setText(tr("0,0,0"));
//    cuboidRotationLabel->setFixedWidth(100);

    modelScaleLabel = new QLabel(this);
    modelScaleLabel->setText(tr("1"));
//    modelScaleLabel->setFixedWidth(100);

    modelRotationLabel = new QLabel(this);
    modelRotationLabel->setText(tr("0,0,0")); // 占位
//    modelRotationLabel->setFixedWidth(100);

    statusBar()->addPermanentWidget(new QLabel(tr("cuboid scale:"), this));
    statusBar()->addPermanentWidget(cuboidScaleLabel); // 添加永久性部件，永久意味着它不能被临时消息（showMessage函数）掩盖，位于最右端，stretch伸缩性为0);
    statusBar()->addPermanentWidget(new QLabel(tr("cuboid rotation:"), this));
    statusBar()->addPermanentWidget(cuboidRotationLabel);
    statusBar()->addPermanentWidget(new QLabel(tr("model scale:"), this));
    statusBar()->addPermanentWidget(modelScaleLabel);
    statusBar()->addPermanentWidget(new QLabel(tr("model rotation:"), this));
    statusBar()->addPermanentWidget(modelRotationLabel);
}

void MainWindow::initCentralWidget()
{
    ModelWidget *modelWidget = new ModelWidget(this);
    setCentralWidget(modelWidget);

    connect(this, SIGNAL(fileOpen(QString)), modelWidget, SLOT(onFileOpen(QString)));
}

void MainWindow::showAbout()
{
    QMessageBox::about(this, tr("About"), tr("Shenzhen Creality 3D Technology Co., Ltd"));
}

//void MainWindow::loadFile(const QString &fileName)
//{
//    QFile file(fileName);
//    if (!file.open(QFile::ReadOnly | QFile::Text))
//    {
//        QMessageBox::warning(this, tr("Application"),
//                             tr("Cannot read file %1:\n%2.")
//                             .arg(QDir::toNativeSeparators(fileName), file.errorString()));
//        return;
//    }

//    QTextStream in(&file);
//#ifndef QT_NO_CURSOR
//    QApplication::setOverrideCursor(Qt::WaitCursor);
//#endif
//    textEdit->setPlainText(in.readAll());
//#ifndef QT_NO_CURSOR
//    QApplication::restoreOverrideCursor();
//#endif

//    setCurrentFile(fileName);
//    statusBar()->showMessage(tr("File loaded"), 2000);
//}

//bool MainWindow::saveFile(const QString &fileName)
//{
//    QFile file(fileName);
//    if (!file.open(QFile::WriteOnly | QFile::Text))
//    {
//        QMessageBox::warning(this, tr("Application"),
//                             tr("Cannot write file %1:\n%2.")
//                             .arg(QDir::toNativeSeparators(fileName),
//                                  file.errorString()));
//        return false;
//    }

//    QTextStream out(&file);
//#ifndef QT_NO_CURSOR
//    QApplication::setOverrideCursor(Qt::WaitCursor);
//#endif
//    out << textEdit->toPlainText();
//#ifndef QT_NO_CURSOR
//    QApplication::restoreOverrideCursor();
//#endif

//    setCurrentFile(fileName);
//    statusBar()->showMessage(tr("File saved"), 2000);
//    return true;
//}

void MainWindow::showOpenFile()
{
    QString settingsFile = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)
                           + "/settings.ini";
    qDebug() << "settings file: " << settingsFile;

    QSettings settings(settingsFile, QSettings::IniFormat);
    QString lastPath = settings.value("LastFilePath").toString();

    QString filePath = QFileDialog::getOpenFileName(this, tr("Open file"), lastPath, "stl files(*.stl)");
    if (!filePath.isEmpty())
    {
        settings.setValue("LastFilePath", filePath); // 记录路径到QSettings中保存
        loadFile(filePath);
    }
}

void MainWindow::loadFile(const QString &filePath)
{
    emit fileOpen(filePath);
//    StlScene *scene = new StlScene(filePath);
//    setCentralWidget(scene);

//    StlWidget *widget = new StlWidget();
//    setCentralWidget(widget);
//    widget->show();

    statusBar()->showMessage(tr("load %1 ok").arg(filePath), 3000);
}

void MainWindow::showOption()
{
    OptionDialog *optionDialog = new OptionDialog(this);
    int ret = optionDialog->exec(); // show(): 非模态  open(): 半模态  exec(): 模态
    if (QDialog::Accepted == ret)
    {
        // save options
    }
}

void MainWindow::langEn()
{
    enAct->setChecked(true);
    zhAct->setChecked(false);
}

void MainWindow::langZh()
{
    enAct->setChecked(false);
    zhAct->setChecked(true);
}

void MainWindow::generateGcode()
{
    QMessageBox::information(this, tr("Info"), "Do nothing now");

    QThread *workerThread = new QThread();
    Generator *generator = new Generator();

    connect(workerThread, SIGNAL(started()), generator, SLOT(doWork()));
    connect(generator, SIGNAL(resultReady(int)), this, SLOT(handleResults(int)));

    // automatically delete thread and task object when work is done:
    connect(workerThread, SIGNAL(finished()), generator, SLOT(deleteLater()));
    connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater()));

    generator->moveToThread(workerThread);
    workerThread->start();
}

void MainWindow::onCuboidScaleChanged(float scale)
{
    cuboidScaleLabel->setText(QString("%1").arg(scale));
}

void MainWindow::onCuboidRotationChanged(float rotationX, float rotationY, float rotationZ)
{
    cuboidRotationLabel->setText(QString("%1,%2,%3").arg(rotationX).arg(rotationY).arg(rotationZ));
}

void MainWindow::onModelScaleChanged(float scale)
{
    modelScaleLabel->setText(QString("%1").arg(scale));
}

void MainWindow::onModelRotationChanged(float rotationX, float rotationY, float rotationZ)
{
    modelRotationLabel->setText(QString("%1,%2,%3").arg(rotationX).arg(rotationY).arg(rotationZ));
}

void MainWindow::handleResults(int rslt)
{
    qDebug() << "receive the resultReady signal---------------------------------";
    qDebug() << "     current thread ID:" << QThread::currentThreadId() << '\n';
    qDebug() << "     the last result is:" << rslt;
}
